import path from 'path';
import fs from 'fs';
//import Logger4node from "../db/proxy/Logger4node";
import Proxys from "../db/proxy/Proxy";
import SimpleHandler from "../db/proxy/SimpleHandler";
import TransactionHandler from "../db/proxy/TransactionHandler";
import InjectRedisHandler from "../db/memerydb/InjectRedisHandler";
/**
 * Bean工厂
 */
export default class BeanFactory {
    constructor() {
        //维护一个注入表
        this.injection = {};

        if (!BeanFactory.instance) {
            this.dirsHandler = [
                { dir: "../api/service", handler: new TransactionHandler() },
                { dir: "../api/wx", handler: new SimpleHandler() },
                { dir: "../api/ding" },
                { dir: "../db/memerydb/KvClient.js",handler:new InjectRedisHandler() }
            ]
            this.loadBeans();
            BeanFactory.instance = this;
            return this;
        }

    }

    /**
     * 装置Bean
     */
    loadBeans() {
        const root = path.join(__dirname);
        for (let i = 0; i < this.dirsHandler.length; i++) {
            const libPath = path.join(root, this.dirsHandler[i].dir);
            this.listFiles(libPath, this.dirsHandler[i].handler);
        }
    }

    //动态加载Bean
    listFiles(root, handler) {
        const isFile = fs.statSync(root);
        if(isFile.isFile()){
            const m = require(root);
            this.bindingHandler(m, handler);
            return;
        }
        const dirs = fs.readdirSync(root);
        for (let i = 0; i < dirs.length; i++) {
            const dir = dirs[i];
            const newPath = path.join(root, dir);
            const info = fs.statSync(newPath);
            if (info.isDirectory()) {
                this.listFiles(newPath, handler);
            } else {
                //引入js类库
                const m = require(newPath);
                this.bindingHandler(m, handler);
            }
        }


    }

    /**
     * 绑定Handler并装入容器（装载的Bean不能重复）
     * @param target
     * @param handler
     */
    bindingHandler(target, handler) {
        const obj = target.default.prototype;
        const name = target.default.name || target.default.__proto__.name;  //装载Bean的名称
            
        Reflect.set(this, name, handler ? Proxys.newProxyInstance(obj, undefined, handler.inject(obj)) : obj)
    }

    /**
     * 依赖注入表
     * @param {*} map 
     */
    setInjectionRelation(beans,filter) {
        if (!Array.isArray(beans)) {
            throw ("注入表应该为数组!");
        }

        for (let i = 0; i < beans.length; i++) {
            const beanName = beans[i];
            for (const key in this) {
                if (this.hasOwnProperty(key)) {
                    const element = this[key];
                    if (!element) {
                        throw ('没有' + key + 'Bean对象');
                    }
                    if (beanName === key || (filter && typeof filter =="function" && filter(key))) {
                        continue;
                    }
                    //console.log(key, beanName);
                    Reflect.set(element, beanName, this[beanName]);
                }
            }
        }

    }


}

module.exports = new BeanFactory();

